package com.cskaoyan.wordmemorize.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cskaoyan.wordmemorize.common.result.Result;
import com.cskaoyan.wordmemorize.converter.RolePermissionConverter;
import com.cskaoyan.wordmemorize.dao.entity.PermissionDO;
import com.cskaoyan.wordmemorize.dao.entity.RoleDO;
import com.cskaoyan.wordmemorize.dao.entity.RolePermissionDO;
import com.cskaoyan.wordmemorize.dao.mapper.PermissionMapper;
import com.cskaoyan.wordmemorize.dao.mapper.RoleMapper;
import com.cskaoyan.wordmemorize.dao.mapper.RolePermissionMapper;
import com.cskaoyan.wordmemorize.dto.admin.*;
import com.cskaoyan.wordmemorize.request.PageRequest;
import com.cskaoyan.wordmemorize.request.PermissionCommand;
import com.cskaoyan.wordmemorize.request.RoleCommand;
import com.cskaoyan.wordmemorize.request.RolePermissionCommand;
import com.cskaoyan.wordmemorize.service.RolePermissionService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


@Service
public class RolePermissionServiceImpl implements RolePermissionService {
    @Resource
    private RolePermissionMapper rolePermissionMapper;
    @Resource
    private PermissionMapper permissionMapper;

    @Resource
    private RolePermissionConverter rolePermissionConverter;

    @Resource
    private RoleMapper roleMapper;
    @Override
    public void savePermissions(PermissionCommand command) {
        PermissionDO permissionDO = rolePermissionConverter.command2PermissionDO(command);
        permissionMapper.insert(permissionDO);
    }
    //建造权限树
    public List<PermissionDTO> buildPermissionTree(List<PermissionDTO> permissions) {

        Map<String, PermissionDTO> permissionMap = permissions.stream()
                .collect(Collectors.toMap(PermissionDTO::getId, permission -> permission));

        List<PermissionDTO> rootPermissions = new ArrayList<>();
        for (PermissionDTO permission : permissions) {
            if ("-1".equals(permission.getParentPermission())) {
                rootPermissions.add(permission);
            } else {
                PermissionDTO parent = permissionMap.get(permission.getParentPermission());
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(permission);
                }
            }
        }

        return rootPermissions;
    }

    @Override
    public List<PermissionDTO> getPermissions() {
//        //获取父权限集合
//          //建立条件构造器
//        LambdaQueryWrapper<PermissionDO> permissionWrapper = new LambdaQueryWrapper<>();
//          //parent_permission为-1的就是父权限
//        permissionWrapper.eq(PermissionDO::getParentPermission, -1);
//        List<PermissionDO> parentPermissionDOS = permissionMapper.selectList(permissionWrapper);
//        List<PermissionDTO> parentPermissionDTOs = rolePermissionConverter.employeePermissionDO2DTO(parentPermissionDOS);
//        //获取每个父权限的子权限集合（首先获取父权限的id，然后去表中匹配parent_permission，相等则为这个父权限的子权限）
//        for (PermissionDTO permissionDTO : parentPermissionDTOs) {
//            //通过父权限id，获得子权限集合
//            LambdaQueryWrapper<PermissionDO> getChildPermissionWrapper =  new LambdaQueryWrapper<>();
//            getChildPermissionWrapper.eq(PermissionDO::getParentPermission, permissionDTO.getId());
//            List<PermissionDO> childPermissionDOS = permissionMapper.selectList(getChildPermissionWrapper);
//            //把这些数据放到PermissionDTO中
//            permissionDTO.setChildren(rolePermissionConverter.employeePermissionDO2DTO(childPermissionDOS));
//        }
        return buildPermissionTree(buildPermissionTree(rolePermissionConverter.employeePermissionDO2DTO(permissionMapper.selectList(null))));
    }

    //递归删除子权限
    private void deleteChildPermissions(Long parentId) {
        // 查询所有直接子权限
        List<PermissionDO> childPermissions = permissionMapper.selectList(
                new LambdaQueryWrapper<PermissionDO>().eq(PermissionDO::getParentPermission, parentId)
        );

        // 递归删除每个子权限的子权限
        for (PermissionDO child : childPermissions) {
            deleteChildPermissions(child.getId());
        }

        // 删除当前层级的所有子权限
        permissionMapper.delete(new LambdaQueryWrapper<PermissionDO>().eq(PermissionDO::getParentPermission, parentId));
    }
    @Override
    public DeletePermissionOperateDTO deletePermission(Long permissionId) {
        //判断是否存在子权限，若存在，递归删除所有子权限
        if (permissionMapper.selectCount(new LambdaQueryWrapper<PermissionDO>().eq(PermissionDO::getParentPermission, permissionId)) > 0) {
            //批量删除所有子权限
            deleteChildPermissions(permissionId);
        }
        // 删除子权限后，再删除当前权限
        permissionMapper.deleteById(permissionId);
        return null;
    }


    @Override
    public void updatePermission(PermissionCommand command) {
        permissionMapper.updateById(rolePermissionConverter.command2PermissionDO(command));
    }

    @Override
    public PageDTO<RoleDTO> getRoleList(PageRequest pageRequest) {
        LambdaQueryWrapper<RoleDO> roleWrapper = new LambdaQueryWrapper<>();
        //pageRequest.getKeyword()是一个关键字，要与数据库的role表中的name字段进行匹配
        if (pageRequest.getKeyword() != null) {
            roleWrapper.like(RoleDO::getName, pageRequest.getKeyword());
        }
        //确定是否需要分页
        if (pageRequest.getPageNum() == null || pageRequest.getCount() == null) {
            //不分页则进行全表查询
            return rolePermissionConverter.roleList2Page(roleMapper.selectList(roleWrapper), 1L);
        }else {
            //进行分页查询
            Page<RoleDO> page = new Page<>(pageRequest.getPageNum(), pageRequest.getCount());
            Page<RoleDO> result = roleMapper.selectPage(page, roleWrapper);
            return rolePermissionConverter.roleList2Page(result.getRecords(), result.getTotal());
        }
    }

    @Override
    public void addRole(RoleCommand command) {

        roleMapper.insert(rolePermissionConverter.command2RoleDO(command));

    }

    @Override
    public void updateRole(RoleCommand roleCommand) {

        roleMapper.updateById(rolePermissionConverter.command2RoleDO(roleCommand));

    }

    @Override
    public void updateRolePermission(RolePermissionCommand command) {
        // 参数校验
        if (command == null || command.getRoleId() == null || command.getPermissions() == null) {
            throw new IllegalArgumentException("角色ID和权限列表不能为空");
        }

        Long roleId = Long.valueOf(command.getRoleId());
        Set<Long> newPermissionIds = command.getPermissions().stream()
                .map(Long::valueOf)
                .collect(Collectors.toSet());

        // 查询当前角色已分配的权限
        List<RolePermissionDO> existingRolePermissions = rolePermissionMapper.selectList(
                new LambdaQueryWrapper<RolePermissionDO>().eq(RolePermissionDO::getRoleId, roleId)
        );

        Set<Long> existingPermissionIds = existingRolePermissions.stream()
                .map(RolePermissionDO::getPermissionId)
                .collect(Collectors.toSet());

        // 计算需要添加和删除的权限
        Set<Long> permissionsToAdd = newPermissionIds.stream()
                .filter(id -> !existingPermissionIds.contains(id))
                .collect(Collectors.toSet());

        Set<Long> permissionsToRemove = existingPermissionIds.stream()
                .filter(id -> !newPermissionIds.contains(id))
                .collect(Collectors.toSet());

        // 执行批量添加和删除
        if (!permissionsToAdd.isEmpty()) {
            List<RolePermissionDO> entitiesToAdd = permissionsToAdd.stream()
                    .map(permissionId -> {
                        RolePermissionDO entity = new RolePermissionDO();
                        entity.setRoleId(roleId);
                        entity.setPermissionId(permissionId);
                        return entity;
                    })
                    .collect(Collectors.toList());

//            rolePermissionMapper.insertBatch(entitiesToAdd); // 需要确保Mapper有批量插入方法
            //利用mybatis-plus提供的插入方法，一次一次的插入
            for (RolePermissionDO entity : entitiesToAdd) {
                rolePermissionMapper.insert(entity);
            }
            }

        if (!permissionsToRemove.isEmpty()) {
            rolePermissionMapper.delete(new LambdaQueryWrapper<RolePermissionDO>()
                    .eq(RolePermissionDO::getRoleId, roleId)
                    .in(RolePermissionDO::getPermissionId, permissionsToRemove));
        }
    }

    @Override
    public RolePermissionDTO getRolePermissionList(Long roleId) {
        //新建个RolePermissionDTO对象
        RolePermissionDTO rolePermissionDTO = new RolePermissionDTO();
        //获取全部权限树
        List<PermissionDTO> permissions = getPermissions();
        //放入
        rolePermissionDTO.setSystemPermissions(permissions);
        //通过roleId在role_permission获取这个角色所拥有的权限Id(只获取非父权限,permission_id)
        LambdaQueryWrapper<RolePermissionDO> rolePermissionWrapper = new LambdaQueryWrapper<>();
        rolePermissionWrapper.eq(RolePermissionDO::getRoleId, roleId);
        List<RolePermissionDO> rolePermissionDOS = rolePermissionMapper.selectList(rolePermissionWrapper);
        //获取这个角色所拥有的权限Id(只获取非父权限,permission_id)，过滤掉父权限（在permission表中所对应的parent_permission值为-1）
        List<String> permissionIds = rolePermissionDOS.stream()
                .filter(rolePermissionDO -> permissionMapper.selectById(rolePermissionDO.getPermissionId()).getParentPermission() == -1)
                .map(rolePermissionDO -> permissionMapper.selectById(rolePermissionDO.getPermissionId()).getId().toString())
                .collect(Collectors.toList());
        //放入
        rolePermissionDTO.setAssignedPermissions(permissionIds);
        return rolePermissionDTO;
    }

    @Override
    public DeleteRoleOperateDTO deleteRole(Long roleId) {
        roleMapper.deleteById(roleId);
        return null;
    }

    @Override
    public DeleteRolePermissionOperateDTO deleteRolePermission(Long roleId, Long permissionId) {
        DeleteRolePermissionOperateDTO deleteRolePermissionOperateDTO = rolePermissionConverter.toDeleteRolePermissionOperateDTO(roleMapper.selectById(roleId), permissionMapper.selectById(permissionId));
        rolePermissionMapper
                .delete(new LambdaQueryWrapper<RolePermissionDO>()
                        .eq(RolePermissionDO::getRoleId, roleId)
                        .eq(RolePermissionDO::getPermissionId, permissionId));
        return null;
    }
}
